共计 6013 个字符,预计需要花费 16 分钟才能阅读完成。
1、根据时序图了解通讯协议格式
根据 HT1622 数据手册中的时序图可知:
1)从 N1 处可知,当 CS 处于低电平时,WR 才有效。
2)从 N2 处可知,当 CS 处于低电平,且当 WR 脚处于上升沿时,DATA 才有效。
3)从 N3 处可知,向 HT1622 传送指令的通讯协议格式为:3 位命令标识 + 9 位指令。
4)从 N4 处可知,向 HT1622 传送数据的通讯协议格式为:3 位命令标识 + 6 位地址 + 4 位数据。
5)从 N5 处可知,向 HT1622 连续传送多组数据,后续数据会自动更新写入到下一个地址。
6)从 N3/N4/N5 处可知,向 HT1622 写入数据时,指令和地址是从高位写入,数据是从低位写入。
二、写驱动函数
由 HT1622 RAM 映射表可知,SEGx 和 其首地址 Addr 的关系(Addr = SEGx * 2),是连续映射的。所以在写入数据时,可以使用 SEGx 代替地址,一次写入 8 位数据(控制 SEGx 下的 8 个 COM),能更简洁直观地对断码屏进行操作。注意,有的屏幕供应商提供的 DataSheet,SEG 是从 1 开始计数,而不是 0。
/***************************************************************
数据传送,其中:
ucDataValue:显示数据、命令 ID 码和数据 ID 码、初始化设置命令代码;
ucBitNum:位的长度(命令 ID 码和数据 ID 码是 3 位,显示数据是 8 位和 4 位,初始化设置命令代码 9 位);
****************************************************************/
void SendNBitToRAM(unsigned char ucDataValue, uint8_t ucBitNum)
{
unsigned char i;
for (i = 0; i < ucBitNum; i++)
{if (ucDataValue & 0x80)
{setb(PORT_HT1622B_DATA, Pin_HT1622B_DATA);
}
else
{clrb(PORT_HT1622B_DATA, Pin_HT1622B_DATA);
}
clrb(PORT_HT1622B_WR, Pin_HT1622B_WR);
_delay_loop_1(2);
setb(PORT_HT1622B_WR, Pin_HT1622B_WR);
_delay_loop_1(2);
ucDataValue = ucDataValue << 1;
}
}
把地址写入 RAM
void SendAddrToRAM(unsigned char ucAddrValue)
{
unsigned char i;
ucAddrValue = ucAddrValue << 2; // 地址数据只有低 6 位,所以要先移掉高两位
for (i = 0; i < 6; i++)
{if (ucAddrValue & 0x80)
{setb(PORT_HT1622B_DATA, Pin_HT1622B_DATA);
}
else
{clrb(PORT_HT1622B_DATA, Pin_HT1622B_DATA);
}
clrb(PORT_HT1622B_WR, Pin_HT1622B_WR);
_delay_loop_1(2);
setb(PORT_HT1622B_WR, Pin_HT1622B_WR);
_delay_loop_1(2);
ucAddrValue = ucAddrValue << 1;
}
}
/**************************************************************
全屏显示,其中:
ucAddrValue:地址
ucDataValue:显示数据
ucSegNum:SEG 数量,屏有多少个 SEG,就传送多少次显示数据
LcdDisplay_All(0x00, LcdDisplay_On, LCD_SEG_NUM);
**************************************************************/
void LcdDisplay_All(unsigned char ucAddrValue, uint8_t ucDataValue, uint8_t ucSegNum)
{
unsigned char i;
clrb(PORT_HT1622B_CS, Pin_HT1622B_CS); // 片选,选中 HT1622
SendNBitToRAM(LCD_MODE_WRITE, 3); // 发送数据码 ID
SendAddrToRAM(ucAddrValue); // 发送地址
for (i = 0; i < ucSegNum; i++) // 连续传送显示数据的时候,地址自动加一
{SendNBitToRAM(ucDataValue, 8); // 传送显示数据
}
setb(PORT_HT1622B_CS, Pin_HT1622B_CS);
}
写 LCD, 发送地址和数
void LcdDisplay_Single_Test()
{clrb(PORT_HT1622B_CS, Pin_HT1622B_CS); // 片选,选中 HT1622
SendNBitToRAM(LCD_MODE_WRITE, 3); // 发送数据码 ID
SendAddrToRAM(0x00); // 发送地址
SendNBitToRAM(0xFF, 8); // 传送显示数据
setb(PORT_HT1622B_CS, Pin_HT1622B_CS);
}
//===========================================================================
// 函数名: WrBit_H
// 功能 : 将数据 data 从高位开始(高 –> 低),写入 cnt 位
// 参数 : data: 写入的数据;cnt: 写入位数
// 返回值: none
//===========================================================================
void WrBit_H(uint8_t data, uint8_t cnt)
{
uint8_t i;
for (i = 0; i < cnt; i++)
{
// 拉低写使能
clrb(PORT_HT1622B_WR, Pin_HT1622B_WR);
_delay_loop_1(2);
if (data & 0x80)
{
// 数据位拉高
setb(PORT_HT1622B_DATA, Pin_HT1622B_DATA);
}
else
{
// 数据线拉低
clrb(PORT_HT1622B_DATA, Pin_HT1622B_DATA);
}
_delay_loop_1(2);
setb(PORT_HT1622B_WR, Pin_HT1622B_WR);
_delay_loop_1(2);
data <<= 1;
}
}
//===========================================================================
// 函数名: WrBit_L
// 功能 : 将数据 data 从低位开始(高 <– 低),写入 cnt 位
// 参数 : data: 写入的数据;cnt: 写入位数
// 返回值: none
//===========================================================================
void WrBit_L(uint8_t data, uint8_t cnt)
{
uint8_t i;
for (i = 0; i < cnt; i++)
{clrb(PORT_HT1622B_WR, Pin_HT1622B_WR);
_delay_loop_1(2);
if (data & 0x01)
{
// 数据位拉高
setb(PORT_HT1622B_DATA, Pin_HT1622B_DATA);
}
else
{
// 数据位拉高
clrb(PORT_HT1622B_DATA, Pin_HT1622B_DATA);
}
_delay_loop_1(2);
setb(PORT_HT1622B_WR, Pin_HT1622B_WR);
_delay_loop_1(2);
data >>= 1;
}
}
//===========================================================================
// 函数名: HT1622WrCmd
// 功能 : 向 HT1622 写入指令
// 参数 : Cmd: 指令代码
// 返回值: none
//===========================================================================
void HT1622WrCmd(uint8_t Cmd)
{clrb(PORT_HT1622B_CS, Pin_HT1622B_CS);
_delay_loop_1(2);
WrBit_H(0x80, 3); // 写入命令标志
WrBit_H(Cmd, 9); // 写入命令数据
setb(PORT_HT1622B_CS, Pin_HT1622B_CS);
_delay_loop_1(2);
}
//===========================================================================
// 函数名: HT1622WrData
// 功能 : 向 HT1622 的 SEGx 写入 8 位数据 (直接控制 SEGx 下的所有内容)
// 参数 : SEGx: 数据映射表中的 SEGx 列;Data: 要写入的控制数据
// 返回值: none
//===========================================================================
void HT1622WrData(uint8_t SEGx, uint16_t Data)
{
uint8_t Addr;
Addr = SEGx * 2;
clrb(PORT_HT1622B_CS, Pin_HT1622B_CS); // 拉低片选
_delay_loop_1(2); // 延时一段时间
WrBit_H(0xA0, 3); // 写入数据标志
WrBit_H(Addr << 2, 6); // 写入 6 位地址
WrBit_L(Data, 8); // 写入 8 位数据
setb(PORT_HT1622B_CS, Pin_HT1622B_CS); // 拉高片选
_delay_loop_1(2); // 延时一段时间
}
//===========================================================================
// 函数名: FullScreenContent
// 功能 : 控制全屏的内容为 显示 / 隐藏
// 参数 : state: 显示状态 (DISPLAY/HIDE)
// 返回值: none
//===========================================================================
void FullScreenContent(uint8_t state)
{clrb(PORT_HT1622B_CS, Pin_HT1622B_CS);
_delay_loop_1(2);
WrBit_H(0xA0, 3); // 写入数据标志
WrBit_H(0x00, 6); // 写入 6 位地址
// 对所有地址写入数据 1/0 —— DISPLAY/HIDE
for (uint16_t i = 0; i < 8 * 32; i++)
{clrb(PORT_HT1622B_WR, Pin_HT1622B_WR);
_delay_loop_1(2);
if (state)
{setb(PORT_HT1622B_DATA, Pin_HT1622B_DATA);
}
else
{clrb(PORT_HT1622B_DATA, Pin_HT1622B_DATA);
}
_delay_loop_1(2);
setb(PORT_HT1622B_WR, Pin_HT1622B_WR);
_delay_loop_1(2);
}
setb(PORT_HT1622B_CS, Pin_HT1622B_CS);
_delay_loop_1(2);
}
1621/1622 初始化函数
void Lcd_init(void)
{
// 片选,选中 HT1622
clrb(PORT_HT1622B_CS, Pin_HT1622B_CS);
SendNBitToRAM(LCD_MODE_CMD, 3); // 发送命令 ID 码
SendNBitToRAM(SYS_EN, 9); // 打开系统时钟
SendNBitToRAM(LCD_DISPLAY_ON, 9); // 打开 LCD 偏置发生器
setb(PORT_HT1622B_CS, Pin_HT1622B_CS);
// 清屏
LcdDisplay_All(0x00, LcdDisplay_Off, LCD_SEG_NUM); // 清屏
}
void LCD_Send_Data(unsigned char address, uint16_t data)
{clrb(PORT_HT1622B_CS, Pin_HT1622B_CS);
// 发送数据码 ID
SendNBitToRAM(LCD_MODE_WRITE, 3);
// 发送地址
SendAddrToRAM(address);
// 发送数据
SendNBitToRAM(data, 8);
setb(PORT_HT1622B_CS, Pin_HT1622B_CS);
}
正文完